package ext.tianma.workflow;

import java.io.Externalizable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;

import com.ptc.core.components.forms.FormProcessingStatus;
import com.ptc.core.components.forms.FormResult;
import com.ptc.core.components.forms.FormResultAction;
import com.ptc.netmarkets.model.NmOid;
import com.ptc.netmarkets.util.beans.NmCommandBean;

import wt.access.AccessControlHelper;
import wt.access.AccessPermission;
import wt.access.AdHocAccessKey;
import wt.access.AdHocControlled;
import wt.clients.vc.CheckInOutTaskLogic;
import wt.fc.ObjectIdentifier;
import wt.fc.ObjectReference;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceServerHelper;
import wt.fc.WTObject;
import wt.folder.CabinetBased;
import wt.folder.FolderHelper;
import wt.inf.container.WTContained;
import wt.inf.container.WTContainer;
import wt.inf.container.WTContainerHelper;
import wt.method.RemoteAccess;
import wt.org.WTPrincipal;
import wt.org.WTPrincipalReference;
import wt.part.WTPart;
import wt.pom.Transaction;
import wt.session.SessionServerHelper;
import wt.team.Team;
import wt.team.TeamHelper;
import wt.team.TeamManaged;
import wt.util.WTException;
import wt.util.WTMessage;
import wt.util.WTPropertyVetoException;
import wt.vc.wip.Workable;
import wt.workflow.engine.ProcessData;
import wt.workflow.engine.WfActivity;
import wt.workflow.engine.WfBlock;
import wt.workflow.engine.WfConnector;
import wt.workflow.engine.WfProcess;
import wt.workflow.work.WorkItem;

public class TwoMaterialsWorkflowUtil implements RemoteAccess, Serializable 
{
	private static String RESOURCE = "ext.tianma.part.partResource";
	
	/**
	 * 判断某一特定对象是否处于检出状态
	 * 
	 * @param wto
	 * @return
	 * @throws WTException
	 * @throws WTPropertyVetoException
	 */
	public static boolean isObjectCheckedOut(WTObject wto) throws WTException, WTPropertyVetoException {
		boolean flag = SessionServerHelper.manager.setAccessEnforced(false);
		try {
			if ((wto instanceof Workable) && (wto instanceof CabinetBased)
					&& (CheckInOutTaskLogic.isCheckedOut((Workable) wto) || FolderHelper.inPersonalCabinet((CabinetBased) wto))) 
			{
				 Object params[] ={ wto.getDisplayIdentifier() };
				 String errorInfo = WTMessage.getLocalizedMessage(RESOURCE, "ischeckout", params);
				 throw new WTException(errorInfo);
				
			}
			else
				return false;
		} 
		 finally {
			SessionServerHelper.manager.setAccessEnforced(flag);
		}
		
	}
	
	/**
	 * 流程中设置特定角色的参与者对pbo的某一指定权限（读取，修改等）
	 * 
	 * @param processObj
	 *            流程本身
	 * @param roleName
	 *            特定角色
	 * @param pbo
	 *            流程PBO
	 * @param ap
	 *            动态权限，如读取、修改等
	 * @throws Exception
	 */
	public static void setAclForRole(Object processObj, String roleName,
			Object pbo, AccessPermission ap) throws Exception {
		if (processObj == null || roleName == null || roleName.length() == 0
				|| pbo == null || ap == null)
			return;
		WfProcess wfprocess = getProcess(processObj);

		// 获取流程 团队的特定角色的参与者
		Team team=getTeam(wfprocess);
		//Team team = (Team) ((TeamReference) ((TeamManaged) wfprocess).getTeamId()).getObject();
		team = (Team) PersistenceHelper.manager.refresh(team);

		wt.project.Role role = (wt.project.Role) (wt.project.Role
				.toRole(roleName));

		Enumeration participants = team.getPrincipalTarget(role);
		;
		if ((participants == null) || (!participants.hasMoreElements()))
			return;

		// 对参与者给予权限
		while (participants.hasMoreElements()) {
			WTPrincipalReference principalRef = (WTPrincipalReference) participants.nextElement();
			WTContainer container = WTContainerHelper.getContainer((WTContained) pbo);
			setObjectAccess((Persistable) pbo, principalRef.getPrincipal(), ap);
		}
	}
	public static Persistable setObjectAccess(Persistable persistable,
			WTPrincipal wtprincipal, AccessPermission accessPermission)
			throws WTException, wt.util.WTPropertyVetoException {
		boolean flag = SessionServerHelper.manager.setAccessEnforced(false);
		Transaction transaction = new Transaction();
		try {
			transaction.start();

			WTPrincipalReference wtprincipalreference = WTPrincipalReference
					.newWTPrincipalReference(wtprincipal);

			Vector vector = new Vector();
			vector.add(accessPermission);

			persistable = PersistenceHelper.manager.refresh(persistable);
			if (persistable instanceof AdHocControlled) {
				AdHocControlled adhoccontrolled = (AdHocControlled) persistable;
				try {
					adhoccontrolled = AccessControlHelper.manager
							.addPermissions(adhoccontrolled,
									wtprincipalreference, vector,
									AdHocAccessKey.WNC_ACCESS_CONTROL);
					PersistenceServerHelper.manager.update(adhoccontrolled,
							false);
					System.out.println("=================== 给权限");
				} catch (Exception exception) {
					
				}

			}

			transaction.commit();
			transaction = null;
			Persistable persistable1 = persistable;
			return persistable1;
		} finally {
			if (transaction != null)
				transaction.rollback();
			SessionServerHelper.manager.setAccessEnforced(flag);
		}
	}
	
	public static Persistable removeObjectAccess(Persistable persistable,
			WTPrincipal wtprincipal, AccessPermission accessPermission)
			throws WTException, wt.util.WTPropertyVetoException {
		boolean flag = SessionServerHelper.manager.setAccessEnforced(false);
		Transaction transaction = new Transaction();
		try {
			transaction.start();

			WTPrincipalReference wtprincipalreference = WTPrincipalReference
					.newWTPrincipalReference(wtprincipal);

			Vector vector = new Vector();
			vector.add(accessPermission);

			persistable = PersistenceHelper.manager.refresh(persistable);
			if (persistable instanceof AdHocControlled) {
				AdHocControlled adhoccontrolled = (AdHocControlled) persistable;
				try {
					adhoccontrolled = AccessControlHelper.manager
							.removePermission(adhoccontrolled,
									wtprincipalreference, accessPermission,
									AdHocAccessKey.WNC_ACCESS_CONTROL);
					PersistenceServerHelper.manager.update(adhoccontrolled,
							false);
					System.out.println("====================================收权限");
				} catch (Exception exception) {
					
				}

			}

			transaction.commit();
			transaction = null;
			Persistable persistable1 = persistable;
			return persistable1;
		} finally {
			if (transaction != null)
				transaction.rollback();
			SessionServerHelper.manager.setAccessEnforced(flag);
		}
	}
	
	public static Persistable setObjectAccess(Persistable persistable,
			WTPrincipalReference wtprincipalreference,
			AccessPermission permission) throws WTException,
			wt.util.WTPropertyVetoException {
		if ((wtprincipalreference == null)
				|| !(persistable instanceof AdHocControlled)
				|| (permission == null))
			return persistable;

		WTPrincipal wtprincipal = wtprincipalreference.getPrincipal();
		persistable = setObjectAccess(persistable, wtprincipal, permission);

		return persistable;
	}
	
	public static Persistable removeObjectAccess(Persistable persistable,
			WTPrincipalReference wtprincipalreference,
			AccessPermission permission) throws WTException,
			wt.util.WTPropertyVetoException {
		if ((wtprincipalreference == null)
				|| !(persistable instanceof AdHocControlled)
				|| (permission == null))
			return persistable;

		WTPrincipal wtprincipal = wtprincipalreference.getPrincipal();
		persistable = removeObjectAccess(persistable, wtprincipal, permission);

		return persistable;
	}

	/**
	 * 流程中取消特定角色的参与者对pbo的某一指定权限（读取，修改等）
	 * 
	 * @param processObj
	 *            流程本身
	 * @param roleName
	 *            特定角色
	 * @param pbo
	 *            流程PBO
	 * @param ap
	 *            动态权限，如读取、修改等
	 * @throws Exception
	 */
	public static void removeAclForRole(Object processObj, String roleName,
			Object pbo, AccessPermission ap) throws Exception {
		if (processObj == null || roleName == null || roleName.length() == 0
				|| pbo == null || ap == null)
			return;
		
		WfProcess wfprocess = getProcess(processObj);

		// 获取流程 团队的特定角色的参与者
		Team team=getTeam(wfprocess);
		//Team team = (Team) ((TeamReference) ((TeamManaged) wfprocess).getTeamId()).getObject();
		team = (Team) PersistenceHelper.manager.refresh(team);

		wt.project.Role role = (wt.project.Role) (wt.project.Role
				.toRole(roleName));

		Enumeration participants = team.getPrincipalTarget(role);
		;
		if ((participants == null) || (!participants.hasMoreElements()))
			return;

		// 取消参与者权限
		while (participants.hasMoreElements()) {
			WTPrincipalReference principalRef = (WTPrincipalReference) participants
					.nextElement();
			WTContainer container = WTContainerHelper
					.getContainer((WTContained) pbo);
			removeObjectAccess((Persistable) pbo, principalRef.getPrincipal(),
					ap);
			System.out.println("==============removeObjectAccess 调用该方法");
		}
	}
	
	
	/**
     *获取流程团队
     * @param process 流程实例
     * @throws WTException
     */
    public static Team getTeam(TeamManaged process) throws WTException
    {
    	System.out.println("@@@@@@@@@@@@@@@@  start 获取流程团队 ");
        return TeamHelper.service.getTeam(process);
    }
    
	public static WfProcess getProcess(Object obj) {
		if (obj == null)
			return null;

		try {
			Persistable persistable = null;

			if (obj instanceof ObjectIdentifier)
				persistable = PersistenceHelper.manager
						.refresh((ObjectIdentifier) obj);
			else if (obj instanceof ObjectReference)
				persistable = ((ObjectReference) obj).getObject();

			if (obj instanceof Persistable)
				persistable = (Persistable) obj;

			if (persistable instanceof WorkItem)
				persistable = ((WorkItem) persistable).getSource().getObject();

			if (persistable instanceof WfActivity)
				persistable = ((WfActivity) persistable).getParentProcess();

			if (persistable instanceof WfConnector)
				persistable = ((WfConnector) persistable).getParentProcessRef()
						.getObject();

			if (persistable instanceof WfBlock)
				persistable = ((WfBlock) persistable).getParentProcess();

			if (persistable instanceof WfProcess)
				return (WfProcess) persistable;
			else
				return null;
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
	
}
